package com.triones.ljr.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtil;
import com.ruoyi.common.utils.StringUtils;
import com.triones.ljr.entity.dto.EnterpriseDO;
import com.triones.ljr.entity.dto.SsEnterpriseDO;
import com.triones.ljr.entity.dto.WxUserDO;
import com.triones.ljr.entity.vo.EnterpriseVO;
import com.triones.ljr.entity.vo.SsEnterpriseVO;
import com.triones.ljr.entity.vo.WxUserVO;
import com.triones.ljr.mapper.EnterpriseMapper;
import com.triones.ljr.mapper.SsEnterpriseMapper;
import com.triones.ljr.mapper.WxUserMapper;
import com.triones.ljr.service.EnterpriseService;
import com.triones.ljr.service.WxUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 企业管理
 */
@Service
@RequiredArgsConstructor
public class EnterpriseServiceImpl implements EnterpriseService {

    private final EnterpriseMapper enterpriseMapper;

    private final WxUserMapper wxUserMapper;

    private final SsEnterpriseMapper ssEnterpriseMapper;

    @Override
    public boolean register(EnterpriseDO dto) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        dto.setStatus("0");
        dto.setWxUserId(loginUser.getUserId());
        dto.setCreateTime(DateUtil.getDateTimeString());
        EnterpriseDO enterpriseDO = enterpriseMapper.selectOne(new LambdaQueryWrapper<EnterpriseDO>().eq(EnterpriseDO::getWxUserId, loginUser.getUserId()));

        SsEnterpriseVO ssEnterpriseVO = ssEnterpriseMapper.selectVoOne(new LambdaQueryWrapper<SsEnterpriseDO>()
            .eq(SsEnterpriseDO::getEnterpriseName, dto.getName())
            .eq(SsEnterpriseDO::getUscc, dto.getUscc())
            .eq(SsEnterpriseDO::getIsDel, "0")
            .last("limit 1"));
        if (ssEnterpriseVO != null) {
            dto.setStatus("1");
            WxUserDO wxUserDO = wxUserMapper.selectById(loginUser.getUserId());
            if (wxUserDO != null) {
                wxUserDO.setTypeMark("1");
                wxUserMapper.updateById(wxUserDO);
            }
        }

        if (enterpriseDO == null) {
            return enterpriseMapper.insert(dto) > 0;
        }
        if (enterpriseDO.getStatus().equals("0")) {
            throw new ServiceException("当前有待审核的注册信息，不允许再次提交注册。");
        } else if (enterpriseDO.getStatus().equals("1") || enterpriseDO.getStatus().equals("2")) {
            throw new ServiceException("当前用户已注册企业!");
        } else {
            dto.setId(enterpriseDO.getId());
            return enterpriseMapper.updateById(dto) > 0;
        }
    }

    @Override
    public TableDataInfo<EnterpriseVO> pageList(EnterpriseDO dto, PageQuery pageQuery) {
        LambdaQueryWrapper<EnterpriseDO> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(dto.getStatus()), EnterpriseDO::getStatus, dto.getStatus())
            .and(StringUtils.isNotBlank(dto.getName()),
                wq -> wq.like(EnterpriseDO::getName, dto.getName()).or()
                    .like(EnterpriseDO::getUscc, dto.getName()).or()
                    .like(EnterpriseDO::getAddress, dto.getName()).or()
                    .like(EnterpriseDO::getLegalRepresentative, dto.getName()).or()
                    .like(EnterpriseDO::getIndustry, dto.getName()).or()
                    .like(EnterpriseDO::getMobile, dto.getName())
            )
            .orderByAsc(EnterpriseDO::getCreateTime);
        Page<EnterpriseVO> result = enterpriseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean audit(EnterpriseDO dto) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        EnterpriseDO enterpriseDO = enterpriseMapper.selectById(dto.getId());
        if (enterpriseDO == null) {
            throw new ServiceException("没有查询到注册信息!");
        }
        if (!enterpriseDO.getStatus().equals("0")) {
            throw new ServiceException("当前注册信息已审核!");
        }
        enterpriseDO.setStatus(dto.getStatus());
        if (dto.getStatus().equals("1")) {
            WxUserDO wxUserDO = wxUserMapper.selectById(enterpriseDO.getWxUserId());
            if (wxUserDO != null) {
                wxUserDO.setTypeMark("1");
                wxUserMapper.updateById(wxUserDO);
            }
        }
        enterpriseDO.setAuditTime(DateUtil.getDateTimeString());
        enterpriseDO.setAuditUserId(loginUser.getUserId());
        enterpriseDO.setAuditUserName(loginUser.getUsername());
        enterpriseDO.setFailRemark(dto.getFailRemark());
        return enterpriseMapper.updateById(enterpriseDO) > 0;
    }

    @Override
    public boolean updateStatus(EnterpriseDO dto) {
        EnterpriseDO enterpriseDO = enterpriseMapper.selectById(dto.getId());
        if (enterpriseDO != null) {
            enterpriseDO.setStatus(dto.getStatus());
            return enterpriseMapper.updateById(enterpriseDO) > 0;
        }
        return false;
    }

    @Override
    public EnterpriseVO getInfo(Long id) {
        return enterpriseMapper.selectVoById(id);
    }

    @Override
    public EnterpriseVO enterpriseInfo() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        return enterpriseMapper.selectVoOne(new LambdaQueryWrapper<EnterpriseDO>()
            .eq(EnterpriseDO::getWxUserId, loginUser.getUserId()).last("limit 1"));
    }

    @Override
    public Boolean checkIsRegister() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        EnterpriseDO enterpriseDO = enterpriseMapper.selectOne(new LambdaQueryWrapper<EnterpriseDO>().eq(EnterpriseDO::getWxUserId, loginUser.getUserId()));
        if (enterpriseDO == null) {
            return true;
        }
        if (enterpriseDO.getStatus().equals("0")) {
            return false;
        } else if (enterpriseDO.getStatus().equals("1") || enterpriseDO.getStatus().equals("2")) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public List<SsEnterpriseVO> getEnterpriseList(String keyword) {
        if (keyword == null || keyword.equals("")) {
            List<SsEnterpriseVO> list = new ArrayList<>();
            return list;
        } else {
            return ssEnterpriseMapper.selectVoList(new LambdaQueryWrapper<SsEnterpriseDO>()
                .like(SsEnterpriseDO::getEnterpriseName, keyword)
                .eq(SsEnterpriseDO::getIsDel, "0"));
        }
    }

    /**
     * 定时计算企业注册过期时间（每天凌晨1点触发）
     */
//    @Scheduled(cron = "0 0 1 * * ?")
    public void calculateExpiration() {
        List<EnterpriseDO> list = enterpriseMapper.selectList(new LambdaQueryWrapper<EnterpriseDO>()
            .in(EnterpriseDO::getStatus, "1", "2"));
        if (list.size() > 0) {
            for (EnterpriseDO enterpriseDO : list) {
                String auditTime = enterpriseDO.getAuditTime();
                if (auditTime != null) {
                    Date date = DateUtil.toDate(auditTime, "yyyy-MM-dd HH:mm:ss");
                    LocalDateTime auditDateTime = LocalDateTime.ofInstant(
                        date.toInstant(),
                        ZoneId.systemDefault()
                    );
                    LocalDateTime threeYearsLater = auditDateTime.plus(3, ChronoUnit.YEARS);
                    LocalDateTime now = LocalDateTime.now();
                    if (threeYearsLater.isBefore(now)) {
                        enterpriseDO.setStatus("3");
                        enterpriseMapper.updateById(enterpriseDO);
                    }
                }
            }
        }
    }
}
